/**********************************************************************************************/
// dgt_BoolFunction.cpp
//
// Common Lib for Digital Studio
// Block of management of bool functions
// Class of elementary bool function
//
// Copyright Diamant Group 2008
/**********************************************************************************************/
#include "dgt_BoolFunction.h"
#include "dgt_Log.h"

/**********************************************************************************************/
dgt_BoolFunction::dgt_BoolFunction()
: m_Kind( AND_OR )
{
	START( "DgtKernel", "dgt_BoolFunction::dgt_BoolFunction" );
	RETURN_VOID( "dgt_BoolFunction::dgt_BoolFunction" );
}

/**********************************************************************************************/
BoolElementArray dgt_BoolFunction::get_Function( void )							
{ 
	START( "DgtKernel", "dgt_BoolFunction::get_Function" );

	RETURN( "dgt_BoolFunction::get_Function", m_BoolFunction );
	return m_BoolFunction;
}

/**********************************************************************************************/
wxArrayString dgt_BoolFunction::get_VarNames( void )							
{
	START( "DgtKernel", "dgt_BoolFunction::get_VarNames" );

	RETURN( "dgt_BoolFunction::get_VarNames", m_VarNames );
	return m_VarNames;
}

/**********************************************************************************************/
NORMAL_KIND	dgt_BoolFunction::get_Kind( void )
{ 
	START( "DgtKernel", "dgt_BoolFunction::get_Kind" );

	RETURN( "dgt_BoolFunction::get_Kind", m_Kind );
	return m_Kind; 
}		


/**********************************************************************************************/
void dgt_BoolFunction::set_Function( BoolElementArray inFunction )
{
	START( "DgtKernel", "dgt_BoolFunction::set_Function" );
	LOG_PARAM( inFunction );

	m_BoolFunction.Clear();

	for( int i = 0; i < inFunction.Count(); i++ )
	{
		dgt_BoolElement_Ptr tElement = inFunction.Item( i );
		m_BoolFunction.Add( tElement );
	}

	RETURN_VOID( "dgt_BoolFunction::set_Function" );
}

/**********************************************************************************************/
void dgt_BoolFunction::set_VarNames( wxArrayString &inVarNames )
{
	START( "DgtKernel", "dgt_BoolFunction::set_VarNames" );
	LOG_PARAM( inVarNames );

	for( int i = 0; i < inVarNames.Count(); i++ )
		m_VarNames.Add( inVarNames.Item( i ) );

	RETURN_VOID( "dgt_BoolFunction::set_VarNames" );
}

/**********************************************************************************************/
void dgt_BoolFunction::set_Kind( NORMAL_KIND inKind )
{
	START( "DgtKernel", "dgt_BoolFunction::set_Kind" );
	LOG_PARAM( inKind );

	m_Kind = inKind; 

	RETURN_VOID( "dgt_BoolFunction::set_Kind" );
}

/**********************************************************************************************/
unsigned dgt_BoolFunction::get_IndexOfSecondOperation( void )
{
	START( "DgtKernel", "dgt_BoolFunction::get_IndexOfSecondOperation" );

	unsigned result;
	BOOL_OPERATION tOp = (BOOL_OPERATION) 0;

	for( unsigned i = 0; i < m_BoolFunction.Count(); i++ )
	{
		dgt_BoolElement_Ptr pEl = m_BoolFunction.Item( i );
		BOOL_OPERATION ElOp = pEl->get_Operation();
		if( tOp != ElOp )
		{
			if( tOp )
			{
				result = i;
				break;
			}
			else
				tOp = ElOp;
		}
	}

//	RETURN( "dgt_BoolFunction::get_IndexOfSecondOperation", result );
	return result;
}

/**********************************************************************************************/
bool operator==(dgt_BoolFunction_Ptr lValue, dgt_BoolFunction_Ptr rValue )
{
	bool result = false;

	if( lValue->m_VarNames.Count() == rValue->m_VarNames.Count() )					// Check count of vars
		if( lValue->m_Kind == rValue->m_Kind )										// Check kind of function
			if( lValue->m_BoolFunction.Count() == rValue->m_BoolFunction.Count() )	// Check count of elements
			{
				for( unsigned i = 0; i < lValue->m_BoolFunction.Count(); i++ )
				{
					dgt_BoolElement_Ptr lElement = lValue->m_BoolFunction.Item( i );
					dgt_BoolElement_Ptr rElement = rValue->m_BoolFunction.Item( i );

					bool flag = false;

					if( lElement->get_Operation() == rElement->get_Operation() )				// Check operation of element
					{	
						wxArrayInt lOpCodes = lElement->get_OpCodes();
						wxArrayInt rOpCodes = rElement->get_OpCodes();

						wxBoolArray lInvArr = lElement->get_Inverts();
						wxBoolArray rInvArr = rElement->get_Inverts();

						if( lElement->Count() == rElement->Count() )		// Check count of operands of element
						{
							for( unsigned j = 0; j < lElement->Count(); j++ )
							{
								int lOp = lOpCodes.Item( j );
								bool lInvert = lInvArr.Item( j );

								int rOp = rOpCodes.Item( j );
								bool rInvert = rInvArr.Item( j );

								if( (lOp != rOp) || ( lInvert != rInvert ) )
									return false;
							}
							flag = true;
						}
					}
					if( !flag )
						return false;
				}

				return true;
			}
	return false;
}
